package cn.jtfadmin.base.lang.common.security;


import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户明细,当前用户信息 使用
 */
@Getter
@Setter
public class UserDetails implements Serializable {


    /**
     *
     */
    private static final long serialVersionUID = 1L;


    // 其他用户明细
    private Set<UserDetails> userDetailsSet = new HashSet<>();


    /**
     * 权限标识
     */
    protected Set<String> permissions = new HashSet<>();


    private Map<String, Object> properties = new HashMap<>();

    public String findRequiredUserIdByType(String type){
        Optional<String> optional = findUserIdByType(type);
        if(!optional.isPresent()){
            throw new RuntimeException("当前用户非"+type+"类型用户");
        }
        return optional.get();
    }

    public Optional<String> findUserIdByType(String type){
        UserDetails userDetailByType = getUserDetailByType(type);
        if(Objects.isNull(userDetailByType)){
            return Optional.empty();
        }
        return Optional.of(userDetailByType.getUserId());
    }


    /**
     * 用户id 当前登录用户主id
     */
    private String userId;

    /**
     * 用户类型，当前登录用户主类型
     */
    private String type;

    /**
     * 显示名称，当前登录用户主名称
     */
    private String displayName;

    /**
     * 账号
     */
    private String username;


    /**
     * 用户头像
     */
    private String headImg;


    /**
     * 创建时间
     */
    private LocalDateTime createDateTime;


    private Object password;


    public void switchType(String type){
        UserDetails back = new UserDetails();
        back.setPassword(this.type);
        back.setPermissions(this.permissions);
        back.setProperties(this.properties);
        back.setUserId(this.userId);
        back.setType(this.type);
        back.setDisplayName(this.displayName);
        back.setHeadImg(this.headImg);
        back.setCreateDateTime(this.createDateTime);
        back.setPassword(this.password);
        Optional<UserDetails> first = userDetailsSet.stream().filter(t -> Objects.equals(t.getType(), type)).findFirst();
//        if(first)
    }



    public UserDetails getUserDetailByType(String type){
        if(Objects.equals(type, this.type)){
            return this;
        }
        Optional<UserDetails> optional = this.getUserDetailsSet().stream().filter(t -> Objects.equals(t.getType(), type)).findFirst();
        if(optional.isPresent()){
            return optional.get();
        }
        return null;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UserDetails that = (UserDetails) o;
        return Objects.equals(userId, that.userId) &&
                Objects.equals(type, that.type);
    }

    @Override
    public int hashCode() {
        return Objects.hash(userId, type);
    }

    public Set<String> allPermissions(){
        Set<String> set = new HashSet<>(permissions);
        for (UserDetails userDetails : userDetailsSet) {
            set.addAll(userDetails.getPermissions());
        }
        return set;
    }



    public Set<String> allUserType(){
        Set<String> set = new HashSet<>();
        set.add(this.type);
        set.addAll(getUserDetailsSet().stream().map(t->t.getType()).collect(Collectors.toSet()));
        return set;
    }


    public Set<UserDetails> getUserDetailsSet() {
        return userDetailsSet;
    }

    public void setUserDetailsSet(Set<UserDetails> userDetailsSet) {
        this.userDetailsSet = userDetailsSet;
    }

    public Set<String> getPermissions() {
        return permissions;
    }

    public void setPermissions(Set<String> permissions) {
        this.permissions = permissions;
    }

    public Map<String, Object> getProperties() {
        return properties;
    }

    public void setProperties(Map<String, Object> properties) {
        this.properties = properties;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getDisplayName() {
        return displayName;
    }

    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }

    public String getHeadImg() {
        return headImg;
    }

    public void setHeadImg(String headImg) {
        this.headImg = headImg;
    }

    public LocalDateTime getCreateDateTime() {
        return createDateTime;
    }

    public void setCreateDateTime(LocalDateTime createDateTime) {
        this.createDateTime = createDateTime;
    }

    public Object getPassword() {
        return password;
    }

    public void setPassword(Object password) {
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}
